import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { randomKey } from '../../utils/utils';
import './index.less';
const defaultOptions = {
  show: false,
  content: '',
  key: ''
};
export class TantuterPopMenu extends Component {
  constructor() {
    super();
    this.state = {
      show: false,
      pops: []
    };
    this.target = null;
  }
  componentDidMount() {
    document.getElementById('root').addEventListener(
      'click',
      e => {
        if (!this.state.pops.length) {
          return;
        }
        this.close();
      },
      true
    );
    document.getElementById('root').addEventListener(
      'contextmenu',
      e => {
        if (!this.state.pops.length) {
          return;
        }
        this.close();
      },
      true
    );
  }
  componentDidUpdate() {
    const current = document.getElementById(this.currentKey);
    if (this.state.pops.length > 0 && current) {
      this.adjustArrowDirection(current, this.clickTarget);
    }
  }

  /**
   *
   * @param {Object} popTarget 弹出菜单对象
   * @param {Object} clickTarget 点击对象
   */
  adjustArrowDirection(popTarget, clickTarget) {
    const wrapW = document.body.offsetWidth - 8; //视口宽度,去除滚动条8px
    const wrapH = document.body.offsetHeight; //视口高度
    const clickTargetMiddleY = clickTarget.top + clickTarget.height / 2; // 点击对象垂直方向居中的top值
    const marginY = 20; // 垂直方向留白偏移量
    const marginX = 6; // 水平方向留白偏移量（箭头位置）
    const arrawSize = 12; //箭头的高宽
    let top = 0;
    let left = 0;
    let arrawTop = 0;
    let arrawLeft = 0;
    let popClass = '';

    //调整垂直方向
    // 箭头垂直居中
    if (
      popTarget.offsetHeight / 2 + clickTargetMiddleY <= wrapH &&
      clickTargetMiddleY - popTarget.offsetHeight / 2 >= 0
    ) {
      top = clickTargetMiddleY - popTarget.offsetHeight / 2;
      arrawTop = popTarget.offsetHeight / 2 - arrawSize / 2;
      //箭头在上方
    } else if (clickTargetMiddleY - marginY >= 0 && popTarget.offsetHeight - marginY + clickTargetMiddleY <= wrapH) {
      top = clickTargetMiddleY - marginY - arrawSize / 2;
      arrawTop = marginY;
      //箭头在下方
    } else if (clickTargetMiddleY + marginY <= wrapH && clickTargetMiddleY - (popTarget.offsetHeight - marginY) >= 0) {
      top = clickTargetMiddleY - (popTarget.offsetHeight - marginY);
      arrawTop = popTarget.offsetHeight - marginY - arrawSize / 2;
      //箭头根据计算，在垂直方向随机位置
    } else {
      top = 2; // 默认有2px,因为阴影需要展现出来
      arrawTop = clickTargetMiddleY - 2 - arrawSize / 2;
    }

    //调整水平方向
    // 箭头在弹窗菜单左侧
    if (popTarget.offsetWidth + clickTarget.right + marginX <= wrapW) {
      left = clickTarget.right + marginX;
      arrawLeft = -12;
      popClass = 'pop-menus-l';
      // 箭头在弹窗菜单右侧
    } else {
      left = clickTarget.left - marginX - popTarget.offsetWidth;
      arrawLeft = popTarget.offsetWidth;
      popClass = 'pop-menus-r';
    }
    popTarget.style.top = top + 'px';
    popTarget.style.left = left + 'px';
    popTarget.querySelector('.pop-menu-arraw').style.top = arrawTop + 'px';
    popTarget.querySelector('.pop-menu-arraw').style.left = arrawLeft + 'px';
    popTarget.querySelector('.pop-menus').className = `pop-menus ${popClass}`;
  }

  open(options, e) {
    const { pops } = this.state;
    this.clickTarget = e.target.getBoundingClientRect();

    defaultOptions.show = true;
    const current = {
      ...defaultOptions,
      key: randomKey(),
      ...options
    };
    if (pops.length > 0) {
      if (!pops.some(item => item.key === current.key)) {
        pops.push(current);
      } else {
        pops.forEach(item => {
          if (item.key === current.key) {
            item = current;
          }
        });
      }
    } else {
      pops.push(current);
    }
    this.setState({
      pops: [...pops]
    });
    this.currentKey = current.key;
    return current.key;
  }

  close(key) {
    if (key) {
      const pops = [...this.state.pops];
      pops.forEach(item => {
        if (item.key === key) {
          item.show = false;
        }
      });
      this.setState({
        pops
      });
      return;
    }
    this.setState({
      pops: []
    });
  }

  componentWillUnmount() {
    document.getElementById('root').removeEventListener(
      'click',
      () => {
        if (!this.state.pops.length) {
          return;
        }
        this.close();
      },
      true
    );
    document.getElementById('root').removeEventListener(
      'contextmenu',
      e => {
        if (!this.state.pops.length) {
          return;
        }
        this.close();
      },
      true
    );
  }
  render() {
    const { pops } = this.state;
    return (
      <>
        {pops.map(item => {
          return (
            <div className="tantuer-pop" key={item.key} id={item.key}>
              <div className="pop-menus" hidden={!item.show}>
                <div className="pop-menu-arraw"></div>
                {item.content}
              </div>
            </div>
          );
        })}
      </>
    );
  }
}

let div = document.createElement('div');
document.body.appendChild(div);
let PopMenu = ReactDOM.render(React.createElement(TantuterPopMenu), div);
export default PopMenu;
